#ifndef AFCORE_DATABASE_DATABASE_DATABASE_QUERY_RESULT_
#define AFCORE_DATABASE_DATABASE_DATABASE_QUERY_RESULT_

#include <vector>

#include "define.h"
#include "database_fwd.h"
#include "nocopyable.h"
#include "database_field.h"

namespace afcore {

/// @brief  数据库
namespace database {

/// @brief  mysql原始语句结果集
class AFCORE_DATABASE_API CResultSet
  : public CNocopyable {
public:
  /// @brief  构造函数 显示
  /// @param  result      mysql查询结果
  /// @param  fields      mysql记录信息
  /// @param  row_count   记录行数量
  /// @param  field_count 字段数量
  CResultSet(SMysqlResult* result, SMysqlField* fields, uint64_t row_count, uint32_t field_count);
  /// @brief  析构函数
  ~CResultSet();

  /// @brief  是否有下一行数据
  /// @return true        存在下一行数据
  /// @return false       不存在下一行数据
  bool NextRow();
  /// @brief  获取查询结果行数量
  /// @return 当前查询结果行数量
  uint64_t GetRowCount() const { return row_count_; };
  /// @brief  获取查询结果字段数量
  /// @return 当前查询结果字段数量
  uint32_t GetFieldCOunt() const { return field_count_; }

  /// @brief  获取
  /// @return 返回当前结果集
  CField* Fetch() const { return current_row_; }
  /// @brief  []操作符重载
  /// @param  index       要获取的记录行索引
  /// @return 返回当前结果集中的指定索引位置的记录行数据
  const CField& operator[](size_t index) const;

private:
  /// @brief  清理数据
  void CleanUp();

protected:
  uint64_t row_count_ {0};          ///< 结果集行数
  CField* current_row_ {nullptr};   ///< 当前结果行
  uint32_t field_count_ {0};        ///< 结果集字段数量
private:
  SMysqlResult* result_ {nullptr};  ///< 查询结果
  SMysqlField* field_ {nullptr};    ///< 字段集合
};

/// @brief  mysql准备语句结果集
class AFCORE_DATABASE_API CPreparedResultSet
  : public CNocopyable {
public:
  /// @brief  构造函数 显示
  /// @param  stmt        mysql预处理信息
  /// @param  result      mysql查询结果
  /// @param  row_count   记录行数量
  /// @param  field_count 字段数量
  CPreparedResultSet(SMysqlStmt* stmt, SMysqlResult* result, uint64_t row_count, uint32_t field_count);
  /// @brief  析构函数
  ~CPreparedResultSet();

  /// @brief  是否有下一行数据
  /// @return true        存在下一行数据
  /// @return false       不存在下一行数据
  bool NextRow();
  /// @brief  获取查询结果行数量
  /// @return 当前查询结果行数量
  uint64_t GetRowCount() const { return row_count_; };
  /// @brief  获取查询结果字段数量
  /// @return 当前查询结果字段数量
  uint32_t GetFieldCOunt() const { return field_count_; }

  /// @brief  获取
  /// @return 返回当前结果集
  CField* Fetch() const;
  /// @brief  []操作符重载
  /// @param  index       要获取的记录行索引
  /// @return 返回当前结果集中的指定索引位置的记录行数据
  const CField& operator[](size_t index) const;

private:
  /// @brief  清理数据
  void CleanUp();
  /// @brief  是否有下一行数据 内用
  /// @return true        存在下一行数据 或者mysql数据被截断
  /// @return false       不存在下一行数据
  /// @note   只允许在构造函数中调用，用来判断是否有下一行数据
  bool _NextRow();

protected:
  std::vector<CField> rows_;        ///< 字段集合
  uint64_t row_count_ {0};          ///< 结果集行数
  uint64_t row_pos_{0};             ///< 行索引
  uint32_t field_count_ {0};        ///< 结果集字段数量
private:
  SMysqlBind* bind_ {nullptr};              ///< mysql绑定
  SMysqlStmt* stmt_ {nullptr};              ///< mysql预处理语句
  SMysqlResult* metadata_result_ {nullptr}; ///< mysql_stmt_result_metadata返回 字段原始数据
};

} // !namespace database

} // !namespace afcore

#endif //! AFCORE_DATABASE_DATABASE_DATABASE_QUERY_RESULT_